/**********************************************************************
Compile : gcc -O3 -o cascade cascade.c optimize_f.c -lm
Usage : ./cascade 11 12 Yeast.txt
**********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

extern float select_matrix (int N, float matrix[N][N], int order[N]);

void print_help ()
{
	printf ("Usage         : ./cascade mode N L inputfile\n");
	printf ("                (./cascade 0 11 12 Yeast.txt)\n");
	printf ("mode          : 0 normal ; 1 triggled circle\n");
	printf ("N             : number of the nodes\n");
	printf ("L             : number of the steps\n");
}

void score_matrix (int N, int L, int pathway[L][N], float matrix[N][N])
{
	int i, j, k;
	float ref[N];

	for (i = 0; i < N; i++)
	{
		ref[i] = i * (L - 1) / ((float) N);
	}

	for (i = 0; i < N; i++)
	{
		for (j = 0; j < N; j++)
		{
			matrix[i][j] = 0.0;

			for (k = 0; k < L - 1; k++)
			{
				matrix[i][j] += pathway[k][i] * fabsf (k - ref[j]);
			}
		}
	}
}

float cascade (int N, int L, int pathway[L][N], int order[N])
{
	float matrix[N][N], score;

	score_matrix (N, L, pathway, matrix);
	
	score = select_matrix (N, matrix, order);

	return score;
}

int main (int argc, char *argv[])
{
	int i, j, k, n, N, L, mode;
	FILE *fp;
	char buf[256];

	if (argc == 1)
	{
		print_help ();
		exit (0);
	}

	mode = atoi (argv[1]);
	N = atoi (argv[2]);
	L = atoi (argv[3]);

	int pathway[L][N], order[N];
	float score;

	fp = fopen (argv[4], "r");
	while (fgets (buf, 256, fp))
	{
		printf ("%s", buf);

		for (i = 0; i < L; i++)
		{
			for (j = 0; j < N; j++)
			{
				fscanf (fp, "%d", &(pathway[i][j]));
			}
			fgets (buf, 256, fp);
		}

		score = cascade (N, L, pathway, order);

		n = 0;
		for (i = mode; i < L - 1; i++)
		{
			for (j = 0; j < N; j++)
			{
				n += pathway[i][j];
			}
		}

		printf ("c Cascade-like score: %4.3f %2d %4.3f\n", score, n, score / ((float) n));

		for (i = 0; i < L; i++)
		{
			for (j = 0; j < N; j++)
			{
				printf ("%d ", pathway[i][order[j]]);
			}
			printf ("\n");
		}
	}
	fclose (fp);

	exit (0);
}
